//
//  BackgroundMaintain.m
//  etionMisc
//
//  Created by wjxfhxy on 14-3-20.
//  Copyright (c) 2014年 GuangZhouXuanWu. All rights reserved.
//

#import "XMSBackgroundMaintain.h"

#import <AVFoundation/AVFoundation.h>

@interface XMSBackgroundMaintain ()<AVAudioPlayerDelegate>
{
    AVAudioPlayer *_player;
    XMSQueueDictionary *_qdBackgroundService;
    void(^suspendBlock)();
    BOOL _isMaintaining;
    XMSDispatchQueueWrapper *_lockQueue;
}

@property(nonatomic,readonly,assign) BOOL isMaintaining;

@end

@implementation XMSBackgroundMaintain

@synthesize isMaintaining = _isMaintaining;

static XMSBackgroundMaintain *s_maintains;

-(id)init
{
#if TARGET_IPHONE_SIMULATOR
    return nil;
#endif
    
    self = [super init];
    
    NSDictionary *dic = [NSDictionary dictionaryWithObjects:@[@"observerUIApplicationDidBecomeActiveNotification:",@"observerUIApplicationWillResignActiveNotification:"] forKeys:@[UIApplicationDidBecomeActiveNotification,UIApplicationWillResignActiveNotification]];
    
    [NSNotificationCenter addObserver:self dictionarySelector:dic];
    
    _qdBackgroundService = [XMSQueueDictionary new];
    
    _isMaintaining = NO;
    
    _lockQueue = [[XMSDispatchQueueWrapper alloc]initWithName:""];
    
    return self;
}

-(void)dealloc
{
    [NSNotificationCenter removeObserver:self];
    [_qdBackgroundService release_mm];
    if(suspendBlock!=NULL)
        Block_release(suspendBlock);
    [_lockQueue release_mm];
    superdealloc_mm;
}

-(void)stopPlayMuteSound
{
    _player.delegate=nil;
    [_player stop];
    ReleaseObj(_player);
    
    AVAudioSession *session=[AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
    [session setActive:NO error:nil];
}

-(void)observerUIApplicationDidBecomeActiveNotification:(NSNotification*)noti
{
//    NSLog(@"播放音乐observerUIApplicationDidBecomeActiveNotification");
    
    [self stopPlayMuteSound];
}

-(void)startPlayMuteSound
{
    AVAudioSession *session=[AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
    [session setActive:YES error:nil];
    
    NSURL *url=[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"mute" ofType:@"mp3"]];
    AVAudioPlayer *player=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
    player.delegate=self;
    player.numberOfLoops=-1;
    player.volume=0;
    [player play];
    _player=[player retain_mm];
}

-(void)observerUIApplicationWillResignActiveNotification:(NSNotification*)noti
{
    [self startPlayMuteSound];
}

- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags
{
//    NSLog(@"播放音乐audioPlayerEndInterruption %d",flags);
//    if(flags==1)
//        [player play];
}

- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error
{
//    NSLog(@"播放音乐audioPlayerDecodeErrorDidOccur %@",error);
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
//    NSLog(@"播放音乐audioPlayerDidFinishPlaying %d",flag);
}

- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
//    NSLog(@"播放音乐audioPlayerBeginInterruption");
//    [player pause];
    _isMaintaining = NO;
    if(suspendBlock!=NULL)
        suspendBlock();
}

-(void)addBackgroundService:(NSDictionary*)service
{
    [service enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        XMSKvPair *pair = [XMSKvPair kvPairWithKey:key value:[XMSKvPair kvPairWithKey:obj value:@"0"]];
        [_qdBackgroundService addKvPairDirect:pair];
    }];
}

-(void)removeBackgroundService:(NSArray*)serviceKey
{
    [_qdBackgroundService removeObjects:serviceKey];
}

-(void)removeAllBackgroundService
{
    [_qdBackgroundService removeAllObjects];
}

-(BOOL)isNeedMaintain
{
    __block BOOL bNeedMaintain=NO;
    
    [_lockQueue dispatchThreadSync:^
    {
        [_qdBackgroundService enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
         {
             XMSKvPair *pair = (XMSKvPair*)obj;
             id<CBackgroundMaintainDelegate> delegate = ((XMSKvPair*)pair.idValue).idKey;
             if([delegate isNeedBackgroundMaintain]==YES)
             {
                 bNeedMaintain=YES;
                 ((XMSKvPair*)pair.idValue).idValue = @"1";
             }
         }];
        
        if(bNeedMaintain==NO)
            [self stopPlayMuteSound];
    }];
    
    return bNeedMaintain;
}

-(void)startMaintainWithSuspendBlock:(void(^)())block
{
    [_lockQueue dispatchThreadSync:^
    {
        if(suspendBlock!=NULL)
            Block_release(suspendBlock);
        suspendBlock = NULL;
        suspendBlock = Block_copy(block);
        _isMaintaining = YES;
    }];
}

-(void)stopMaintain
{
    [_lockQueue dispatchThreadSync:^
    {
        if(suspendBlock!=NULL)
            Block_release(suspendBlock);
        suspendBlock = NULL;
        _isMaintaining = NO;
        [self resetMaintain];
    }];
}

-(void)resetMaintain
{
    [_qdBackgroundService enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
    {
        XMSKvPair *pair = (XMSKvPair*)obj;
        ((XMSKvPair*)pair.idValue).idValue = @"0";
    }];
}

-(BOOL)stopMaintainIfMaintaining
{
    __block BOOL isMaintaning = NO;
    [_lockQueue dispatchThreadSync:^
    {
        if(_isMaintaining==YES)
        {
            isMaintaning = YES;
            [self stopMaintain];
        }
    }];
    return isMaintaning;
}

-(BOOL)isBackgrounsService:(NSString*)serviceKey
{
    return [_qdBackgroundService kvPairAtKey:serviceKey]!=nil?YES:NO;
}

-(void)terminateMaintain
{
    [_lockQueue dispatchThreadSync:^
    {
        if(suspendBlock!=NULL)
            suspendBlock();
        [self stopMaintain];
        [self stopPlayMuteSound];
    }];
}

+(void)initBackgroundMaintain
{
    if(s_maintains == nil)
        s_maintains = [XMSBackgroundMaintain new];
}

+(void)releaseBackgroundMaintain
{
    [s_maintains stopPlayMuteSound];
    ReleaseObj(s_maintains);
}

+(void)addBackgroundService:(NSDictionary*)service
{
    [s_maintains addBackgroundService:service];
}

+(void)removeBackgroundService:(NSArray*)serviceKey
{
    [s_maintains removeBackgroundService:serviceKey];
}

+(void)removeAllBackgroundService
{
    [s_maintains removeAllBackgroundService];
}

+(BOOL)isNeedMaintain
{
    if(s_maintains==nil)
        return NO;
    return [s_maintains isNeedMaintain];
}

+(void)startMaintainWithSuspendBlock:(void(^)())block
{
    [s_maintains startMaintainWithSuspendBlock:block];
}

//+(void)stopMaintain
//{
//    [s_maintains stopMaintain];
//}
//
//+(BOOL)isMaintaining
//{
//    return s_maintains.isMaintaining;
//}

+(BOOL)stopMaintainIfMaintaining
{
    return [s_maintains stopMaintainIfMaintaining];
}

+(BOOL)isBackgrounsService:(NSString*)serviceKey
{
    return [s_maintains isBackgrounsService:serviceKey];
}

+(void)terminateMaintain
{
    [s_maintains terminateMaintain];
}

@end

@implementation XMSBackgroundMaintain (BackgroundService)

-(void)backgroundTaskIsFinished:(NSString*)serviceKey
{
    UIApplicationState state = [UIApplication sharedApplication].applicationState;
    if(state == UIApplicationStateBackground)
    {
        [_lockQueue dispatchThreadAsync:^
        {
            XMSKvPair *pair = [_qdBackgroundService kvPairAtKey:serviceKey];
            ((XMSKvPair*)pair.idValue).idValue = @"0";
            
            __block BOOL allFinish = YES;
            [_qdBackgroundService enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
            {
                XMSKvPair *pair = (XMSKvPair*)obj;
                if([((XMSKvPair*)pair.idValue).idValue isEqualToString:@"1"])
                    allFinish = NO;
            }];
            
            if(allFinish==YES)
            {
                if(suspendBlock!=NULL)
                    suspendBlock();
                [self stopMaintain];
                [self stopPlayMuteSound];
            }
        }];
    }
}

+(void)backgroundTaskIsFinished:(NSString*)serviceKey
{
    [s_maintains backgroundTaskIsFinished:serviceKey];
}

@end
